<?php

namespace Xrfg\Api\Trading\Spot\Resources;

use App\Http\Resources\Resource;
use Carbon\Carbon;
use Illuminate\Support\Facades\Redis;
use Throwable;
use Xrfg\Core\Trading\Spot\Models\Kline;
use Xrfg\Core\Trading\Spot\Models\Pair;

class SymbolResource extends Resource
{
    public function toArray($request)
    {
        list($open, $close, $high, $low, $number, $total) = $this->getTicker();

        /* @var Pair $this */
        return [
            'id' => $this->id,
            'symbol' => $this->symbol,
            'status' => $this->status,
            'coin_name' => $this->coin_name,
            'coin_id' => $this->coin_id,
            'coin_decimals' => $this->coin_decimals,
            'market_name' => $this->market_name,
            'market_id' => $this->market_id,
            'market_decimals' => $this->market_decimals,
            'price_step' => $this->price_step,
            'number_min' => $this->number_min,
            'number_step' => $this->number_step,
            'total_min' => $this->total_min,
            'open' => $open,
            'close' => $close,
            'high' => $high,
            'low' => $low,
            'number' => $number,
            'total' => $total,
        ];
    }

    private function getTicker()
    {
        /** @var Pair $this */
        if (in_array($this->symbol, array_keys(config('huobi')))) {
            return $this->getHuobiTicker();
        }

        $openTime = Carbon::now()->subDay()->timestamp;
        try {
            /** @var Pair $this */
            $open = (new Kline($this->symbol, 1))
                ->where('time_open', '>=', $openTime)
                ->orderBy('time_open', 'asc')
                ->value('price_open') ?: '0.00000000';
        } catch (Throwable $exception) {
            $open = '0.00000000';
        }

        try {
            /** @var Pair $this */
            $close = (new Kline($this->symbol, 1))
                ->orderBy('time_open', 'desc')
                ->value('price_close') ?: '0.00000000';
        } catch (Throwable $exception) {
            $close = '0.00000000';
        }

        try {
            /** @var Pair $this */
            $twentyFourHours = (new Kline($this->symbol, 60))
                ->where('time_open', '>=', $openTime)
                ->orderBy('time_open', 'desc')
                ->get();
            $high = $twentyFourHours->max('price_high') ?: '0.00000000';
            $low = $twentyFourHours->min('price_low') ?: '0.00000000';
            $number = number_format($twentyFourHours->sum('trades_number'), 8, '.', '');
            $total = number_format($twentyFourHours->sum('trades_total'), 8, '.', '');
        } catch (Throwable $exception) {
            $high = '0.00000000';
            $low = '0.00000000';
            $number = '0.00000000';
            $total = '0.00000000';
        }

        return [$open, $close, $high, $low, $number, $total];
    }

    private function getHuobiTicker()
    {
        /** @var Pair $this */
        $symbol = strtolower(str_replace('/', '', $this->symbol));
        $redis = Redis::connection();
        $ticker = $redis->get('huobi:ticker:'.$symbol);
        if (!$ticker) {
            return [
                '0.00000000',
                '0.00000000',
                '0.00000000',
                '0.00000000',
                '0.00000000',
                '0.00000000',
            ];
        } else {
            $ticker = json_decode($ticker, true);

            return [
                $ticker['open'],
                $ticker['close'],
                $ticker['high'],
                $ticker['low'],
                $ticker['number'],
                $ticker['total'],
            ];
        }
    }
}
